package org.example.business_logic.action;

import javafx.util.Pair;
import org.example.business_logic.component.Baffle;
import org.example.physics_engine.collision.detector.BasicCollisionDetector;
import org.example.physics_engine.collision.manifold.Manifold;
import org.example.physics_engine.body.PhysicsBody;

import java.util.ArrayList;
import java.util.List;

import static org.example.business_logic.Settings.DEFAULT_BAFFLE_ANGULAR;
import static org.example.business_logic.Settings.DEFAULT_BAFFLE_ROTATION;

public class BaffleAction implements UpdateListener {
    private final List<PhysicsBody> balls;

    private final List<PhysicsBody> baffles;

    private final BasicCollisionDetector basicCollisionDetector = new BasicCollisionDetector();

    public BaffleAction(List<PhysicsBody> balls, List<PhysicsBody> baffles) {
        this.balls = balls;
        this.baffles = baffles;
    }


    @Override
    public List<Pair<Manifold, Pair<PhysicsBody, PhysicsBody>>> tick() {
        updatePosition(baffles);
        return basicCollisionDetector.detect(balls, baffles, new ArrayList<>());
    }

    /**
     * 每个tick更新挡板位置
     *
     * @param baffles
     */
    private void updatePosition(List<PhysicsBody> baffles) {
        for (PhysicsBody physicsBody : baffles) {
            Baffle baffle = (Baffle) physicsBody.getShape();
            double angular = baffle.getAngular();
            //上升状态
            if (baffle.isUp()) {
                //还未转到30度，继续旋转
                if (angular < 30) {
                    setUpVelocity(physicsBody);
                    baffle.flip(DEFAULT_BAFFLE_ROTATION);
                    continue;
                }
                //转至30度，停止
                physicsBody.setAngularVelocity(0);
            } else { //下降状态
                //还未归位，继续归位
                if (baffle.getAngular() > 0) {
                    setDownVelocity(physicsBody);
                    baffle.flip(-DEFAULT_BAFFLE_ROTATION);
                } else if (baffle.getAngular() == 0) {
                    physicsBody.setAngularVelocity(0);
                }
            }
        }
    }

    private void setUpVelocity(PhysicsBody physicsBody) {
        Baffle baffle = (Baffle) physicsBody.getShape();
        if (baffle.getDirection() == Baffle.Direction.LEFT) {
            physicsBody.setAngularVelocity(DEFAULT_BAFFLE_ANGULAR);
        } else {
            physicsBody.setAngularVelocity(-DEFAULT_BAFFLE_ANGULAR);
        }
    }

    private void setDownVelocity(PhysicsBody physicsBody) {
        Baffle baffle = (Baffle) physicsBody.getShape();
        if (baffle.getDirection() == Baffle.Direction.LEFT) {
            physicsBody.setAngularVelocity(-DEFAULT_BAFFLE_ANGULAR);
        } else {
            physicsBody.setAngularVelocity(DEFAULT_BAFFLE_ANGULAR);
        }
    }

}
